package view.componentes;

import javax.swing.text.AttributeSet;  
import javax.swing.text.BadLocationException;  
import javax.swing.text.DocumentFilter;

public class CustomDocumentFilter extends DocumentFilter {  

	public static final int SO_NUMEROS = 0;  
	public static final int SO_LETRAS = 1;
	public static final int SEM_RESTRICAO = -1;

	public static final String MAIUSCULAS = "UPPER";
	public static final String MINUSCULAS = "lower";
	public static final String PADRAO = "";

	private String expressaoRegular;  
	private int tamanhoMaximo;
	private String tipoCase;

	public static CustomDocumentFilter criar(int tipoExpressaoRegular, String tipoCase, int tamanhoMaximo) {  

		switch (tipoExpressaoRegular) {  
		case SO_NUMEROS:  
			return new CustomDocumentFilter("[^0-9]", tipoCase, tamanhoMaximo);           
		case SO_LETRAS:  
			return new CustomDocumentFilter("[0-9]", tipoCase, tamanhoMaximo);              
		default:  
			return new CustomDocumentFilter("", tipoCase, tamanhoMaximo);             
		}

	}  

	public static CustomDocumentFilter criar(String expressaoRegular, String tipoCase, int tamanhoMaximo) {  
		return new CustomDocumentFilter(expressaoRegular, tipoCase, tamanhoMaximo);     
	}  

	private CustomDocumentFilter(String expressaoRegular, String tipoCase, int tamanhoMaximo) {  
		super();  
		this.expressaoRegular = expressaoRegular;  
		this.tamanhoMaximo = tamanhoMaximo;
		this.tipoCase = tipoCase;
	}  

	@Override  
	public void insertString(FilterBypass fb, int offset, String text,  
			AttributeSet attr) throws BadLocationException {  

		if (text == null)
			return;
		// aceitara qualquer no. de caracteres
		if (tamanhoMaximo <= 0) {

			if (tipoCase.equalsIgnoreCase(MINUSCULAS)) {
				//transforma para maiusculas antes de inserir
				fb.insertString(offset, text.replaceAll(this.expressaoRegular, "").toLowerCase(), attr);
				return;
			} else if (tipoCase.equalsIgnoreCase(MAIUSCULAS)) {
				//transforma para maiusculas antes de inserir
				fb.insertString(offset, text.replaceAll(this.expressaoRegular, "").toUpperCase(), attr);
				return;
			} else {
				fb.insertString(offset, text.replaceAll(this.expressaoRegular, ""), attr);
				return;
			}

		}

		int ilen = (fb.getDocument().getLength() + text.length());
		// se o comprimento final for menor...
		if (ilen <= tamanhoMaximo) {
			if (tipoCase.equalsIgnoreCase(MINUSCULAS)) {
				//transforma para minusculas antes de inserir
				fb.insertString(offset, text.replaceAll(this.expressaoRegular, "").toLowerCase(), attr);
			} else if (tipoCase.equalsIgnoreCase(MAIUSCULAS)) {
				//transforma para maiusculas antes de inserir
				fb.insertString(offset, text.replaceAll(this.expressaoRegular, "").toUpperCase(), attr);
			} else {
				fb.insertString(offset, text.replaceAll(this.expressaoRegular, ""), attr);
			} // ...aceita str
		} else {

			if (fb.getDocument().getLength() == tamanhoMaximo){
				return; // nada a fazer
			}

			String newStr = text.substring(0, (tamanhoMaximo - fb.getDocument().getLength()));

			if (tipoCase.equalsIgnoreCase(MINUSCULAS)) {
				//transforma para minusculas antes de inserir
				fb.insertString(offset, newStr.replaceAll(this.expressaoRegular, "").toLowerCase(), attr);
			} else if (tipoCase.equalsIgnoreCase(MAIUSCULAS)) {
				//transforma para maiusculas antes de inserir
				fb.insertString(offset, newStr.replaceAll(this.expressaoRegular, "").toUpperCase(), attr);
			} else {
				fb.insertString(offset, newStr.replaceAll(this.expressaoRegular, ""), attr);
			}
		}

	}  

	@Override  
	public void replace(FilterBypass fb, int offset, int length, String text,  
			AttributeSet attrs) throws BadLocationException { 

		if (text == null)
			return;

		if (tamanhoMaximo <= 0) {

			if (tipoCase.equalsIgnoreCase(MINUSCULAS)) {
				//transforma para minusculas antes de inserir
				fb.replace(offset, length, text.replaceAll(this.expressaoRegular, "").toLowerCase(), attrs);
				return;
			} else if (tipoCase.equalsIgnoreCase(MAIUSCULAS)) {
				//transforma para maiusculas antes de inserir
				fb.replace(offset, length, text.replaceAll(this.expressaoRegular, "").toUpperCase(), attrs);
				return;
			} else {
				fb.replace(offset, length, text.replaceAll(this.expressaoRegular, ""), attrs);
				return;
			}

		}

		int ilen = (fb.getDocument().getLength() + text.length() -length);
		// se o comprimento final for menor...
		if (ilen <= tamanhoMaximo) {

			if (tipoCase.equalsIgnoreCase(MINUSCULAS)) {
				fb.replace(offset, length, text.replaceAll(this.expressaoRegular, "").toLowerCase(), attrs);
			} else if (tipoCase.equalsIgnoreCase(MAIUSCULAS)) {
				//transforma para maiusculas antes de inserir
				fb.replace(offset, length, text.replaceAll(this.expressaoRegular, "").toUpperCase(), attrs);
			} else {
				fb.replace(offset, length, text.replaceAll(this.expressaoRegular, ""), attrs);
			}// ...aceita str
		} else {

			if (fb.getDocument().getLength() == tamanhoMaximo){
				return; // nada a fazer
			}

			String newStr = text.substring(0, (tamanhoMaximo - fb.getDocument().getLength() - length));

			if (tipoCase.equalsIgnoreCase(MINUSCULAS)) {
				fb.replace(offset, length, newStr.replaceAll(this.expressaoRegular, "").toLowerCase(), attrs);
			} else if (tipoCase.equalsIgnoreCase(MAIUSCULAS)) {
				fb.replace(offset, length, newStr.replaceAll(this.expressaoRegular, "").toUpperCase(), attrs); 
			} else {
				fb.replace(offset, length, newStr.replaceAll(this.expressaoRegular, ""), attrs);
			}

		}

	}

}  